﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.SolveCranks.CApSCSolveCranksAlgorithm
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.EndModelingEntityLevel;
using EngineeringInternalExtension;
using EngineeringInternalExtension.ModelObjects;
using System;
using System.Collections;
using System.Collections.Generic;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.PrivateImplementationDetails;


namespace DnProcessSimulateCommands.SolveCranks;

public class CApSCSolveCranksAlgorithm
{
  public const string ERR_CODE_CRANK_ERR_PLANE = "APP_CRANK_ERR_PLANE";
  public const string ERR_CODE_CRANK_ERR_LINKS_DATA = "APP_CRANK_ERR_LINKS_DATA";
  public const string ERR_CODE_CRANK_ERR_SIDE_LENGTHS = "APP_CRANK_ERR_SIDE_LENGTHS";
  public const string ERR_CODE_CRANK_CRANK_ERR_ANGLES = "APP_CRANK_ERR_ANGLES";
  public const string ERR_CODE_CRANK_CRANK_ERR_JOINTS_DATA = "APP_CRANK_ERR_JOINTS_DATA";
  public const string ERR_CODE_CRANK_ERR_JOINT_FUNC = "APP_CRANK_ERR_JOINT_FUNC";
  public const string ERR_CODE_DEVICE_COMPILATION_VERIFICATION_ERROR = "CAPSCSOLVECRANKSALGORITHM_DEVICE_COMPILATION_VERIFICATION_ERROR";
  public const string WARNING_CODE_SOLVE_CRANKS_RENAMED_JOINT = "APP_SOLVE_CRANKS_RENAMED_JOINT";
  public const string WARNING_CODE_SOLVE_CRANKS_DRIVING_JOINT_CHOSEN_BY_ALPHABETIC_ORDER = "APP_SOLVE_CRANKS_DRIVING_JOINT_CHOSEN_BY_ALPHABETIC_ORDER";
  private readonly ITxKinematicsModellable _object;
  private CApSCSolveCranksAlgorithm.Result _result;
  private ITxComponent _storedModelingWorkingSpace;
  private bool _shouldRestoreCurrentModelinWorkingSpace;
  private bool _isSolveCranksExecuted;

  public CApSCSolveCranksAlgorithm(ITxKinematicsModellable obj) => this._object = obj;

  public CApSCSolveCranksAlgorithm.Result Execute()
  {
    if (this._result == null)
    {
      this.PerformBeginActions();
      this.SolveCranks();
      this.PerformEndActions();
      if (this._isSolveCranksExecuted)
        this.ClearAllTransactions();
    }
    return this._result;
  }

  private void PerformBeginActions()
  {
    this.ValidDeviceVerification();
    this.StoreModelingWorkingSpaceAction();
    this.OpenForModelingAction();
  }

  private void PerformEndActions()
  {
    this.EndModelingAction();
    this.RestoreModelingWorkingSpaceAction();
  }

  private void SolveCranks()
  {
    if (this._result != null)
      return;
    try
    {
      TxErrorStack.Clear();
      ITxKinematicsModellableEx.SolveCranks(this._object);
      this._result = !this.IsValidDeviceAfterSolve() ? new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.Failiure, "CAPSCSOLVECRANKSALGORITHM_DEVICE_COMPILATION_VERIFICATION_ERROR") : new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.Success);
    }
    catch (Exception ex)
    {
      switch (ex)
      {
        case TxNotOpenForKinematicsModelingException _:
          this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.CannotOpenForKinematicsModeling);
          break;
        case TxSolveCranksFailedException _:
          this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.Failiure, this.GetSolveCranksFailedErrorCode());
          break;
        default:
          this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.Unknown);
          break;
      }
    }
    this._result.Warnings = this.GetSolveCranksWarnings();
    this._isSolveCranksExecuted = true;
  }

  private void StoreModelingWorkingSpaceAction()
  {
    if (this._storedModelingWorkingSpace != null || this._result != null)
      return;
    this._storedModelingWorkingSpace = TxApplication.ActiveDocument.CurrentModelingWorkingSpace;
    this._shouldRestoreCurrentModelinWorkingSpace = true;
  }

  private void RestoreModelingWorkingSpaceAction()
  {
    if (!this._shouldRestoreCurrentModelinWorkingSpace || this._storedModelingWorkingSpace == TxApplication.ActiveDocument.CurrentModelingWorkingSpace)
      return;
    if (this._storedModelingWorkingSpace != null)
      TxDocumentEx.SetCurrentModelingWorkingSpace(this._storedModelingWorkingSpace);
    else
      TxDocumentEx.SetCellAsCurrentModelingWorkingSpace();
  }

  private void OpenForModelingAction()
  {
    if (this._result != null)
      return;
    try
    {
      if (this._object.IsOpenForKinematicsModeling)
        return;
      (this._object as ITxComponent).SetModelingScope();
      if (this._object.IsOpenForKinematicsModeling)
        return;
      this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.CannotOpenForKinematicsModeling);
    }
    catch (Exception ex)
    {
      this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.CannotOpenForKinematicsModeling);
    }
  }

  private void EndModelingAction()
  {
    if (this._result == null || !this._isSolveCranksExecuted)
      return;
    if (this._result.Status == CApSCSolveCranksAlgorithm.Result.eStatus.Success)
    {
      if (this.EndModeling())
        return;
      this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.EndModelingFailed);
    }
    else
    {
      if (this.ReloadComponent())
        return;
      this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.ReloadComponentFailed);
    }
  }

  private bool EndModeling()
  {
    bool flag = false;
    if (this.IsTcAnyPlatform())
    {
      try
      {
        CApEMEndModelingEntityLevelApp modelingEntityLevelApp = new CApEMEndModelingEntityLevelApp(this._object as ITxComponent);
        modelingEntityLevelApp.ConsiderNonModelingStateWithoutUI = true;
        if (modelingEntityLevelApp.ComponentEndModeling())
        {
          this.ClearAllTransactions();
          TxComponentEx.CopyScopeToRevision((this._object as ITxStorable).StorageObject as TxLocalStorage, modelingEntityLevelApp.ReloadInDetailRepresentation ? (TxRepresentationLevel) 5 : (TxRepresentationLevel) 4, modelingEntityLevelApp.ReloadPMIs);
          this.ClearAllTransactions();
          flag = true;
        }
      }
      catch (Exception ex)
      {
        flag = false;
      }
    }
    else
      flag = true;
    return flag;
  }

  private bool ReloadComponent()
  {
    bool flag;
    if (this.IsTcAnyPlatform())
    {
      try
      {
        this.ClearAllTransactions();
        ((this._object as ITxStorable).StorageObject as TxLocalStorage).ReloadFromLibrary();
        this.ClearAllTransactions();
        flag = true;
      }
      catch (Exception ex)
      {
        flag = false;
      }
    }
    else
      flag = true;
    return flag;
  }

  private bool IsTcAnyPlatform() => TxTcUtilities.IsTcAnyPlatform;

  private void ClearAllTransactions()
  {
    TxApplication.ActiveDocument.UndoManager.ClearAllTransactions();
  }

  private string GetSolveCranksFailedErrorCode()
  {
    string cranksFailedErrorCode = (string) null;
    if (TxErrorStack.Contains("APP_CRANK_ERR_PLANE"))
      cranksFailedErrorCode = "APP_CRANK_ERR_PLANE";
    else if (TxErrorStack.Contains("APP_CRANK_ERR_LINKS_DATA"))
      cranksFailedErrorCode = "APP_CRANK_ERR_LINKS_DATA";
    else if (TxErrorStack.Contains("APP_CRANK_ERR_SIDE_LENGTHS"))
      cranksFailedErrorCode = "APP_CRANK_ERR_SIDE_LENGTHS";
    else if (TxErrorStack.Contains("APP_CRANK_ERR_ANGLES"))
      cranksFailedErrorCode = "APP_CRANK_ERR_ANGLES";
    else if (TxErrorStack.Contains("APP_CRANK_ERR_JOINTS_DATA"))
      cranksFailedErrorCode = "APP_CRANK_ERR_JOINTS_DATA";
    else if (TxErrorStack.Contains("APP_CRANK_ERR_JOINT_FUNC"))
      cranksFailedErrorCode = "APP_CRANK_ERR_JOINT_FUNC";
    return cranksFailedErrorCode;
  }

  private bool IsValidDeviceAfterSolve() => this.GetComponentActualRepresentation() is ITxDevice;

  private ITxKinematicsModellable GetComponentActualRepresentation()
  {
    return TxComponentEx.GetActualEngineeringRepresentation(this._object as ITxComponent) as ITxKinematicsModellable;
  }

  private void ValidDeviceVerification()
  {
    if (this._result != null || !(this._object is ITxDevice))
      return;
    this._result = new CApSCSolveCranksAlgorithm.Result(this._object, CApSCSolveCranksAlgorithm.Result.eStatus.AlreadyOK);
  }

  private List<CApSCSolveCranksAlgorithm.Warning> GetSolveCranksWarnings()
  {
    List<CApSCSolveCranksAlgorithm.Warning> solveCranksWarnings = new List<CApSCSolveCranksAlgorithm.Warning>();
    if (TxErrorStack.Contains("APP_SOLVE_CRANKS_DRIVING_JOINT_CHOSEN_BY_ALPHABETIC_ORDER"))
      solveCranksWarnings.AddRange((IEnumerable<CApSCSolveCranksAlgorithm.Warning>) this.CreateWarnings("APP_SOLVE_CRANKS_DRIVING_JOINT_CHOSEN_BY_ALPHABETIC_ORDER"));
    if (TxErrorStack.Contains("APP_SOLVE_CRANKS_RENAMED_JOINT"))
      solveCranksWarnings.AddRange((IEnumerable<CApSCSolveCranksAlgorithm.Warning>) this.CreateWarnings("APP_SOLVE_CRANKS_RENAMED_JOINT"));
    return solveCranksWarnings;
  }

  private List<CApSCSolveCranksAlgorithm.Warning> CreateWarnings(string warningCode)
  {
    List<CApSCSolveCranksAlgorithm.Warning> warnings = new List<CApSCSolveCranksAlgorithm.Warning>();
    ArrayList allParameters = TxErrorStack.GetAllParameters(warningCode);
    if (allParameters != null && allParameters.Count > 0)
    {
      foreach (object obj in allParameters)
      {
        if (obj is IEnumerable<string> warningParams)
          warnings.Add(this.CreateWarning(warningCode, warningParams));
      }
    }
    return warnings;
  }

  private CApSCSolveCranksAlgorithm.Warning CreateWarning(
    string warningCode,
    IEnumerable<string> warningParams)
  {
    return new CApSCSolveCranksAlgorithm.Warning(warningCode, new List<string>(warningParams));
  }

  public class Warning
  {
    public readonly string Code;
    public readonly List<string> Params;

    public Warning(string code, List<string> warningParams)
    {
      this.Code = code;
      this.Params = warningParams;
    }
  }

  public class Result
  {
    public readonly ITxKinematicsModellable Object;
    public readonly CApSCSolveCranksAlgorithm.Result.eStatus Status;
    public readonly string ErrorCode;
    public List<CApSCSolveCranksAlgorithm.Warning> Warnings;

    public Result(
      ITxKinematicsModellable obj,
      CApSCSolveCranksAlgorithm.Result.eStatus status,
      string errorCode = null,
      List<CApSCSolveCranksAlgorithm.Warning> warnings = null)
    {
      this.Object = obj;
      this.Status = status;
      this.ErrorCode = errorCode;
      this.Warnings = warnings;
    }

    public enum eStatus
    {
      Unknown,
      AlreadyOK,
      Success,
      CannotOpenForKinematicsModeling,
      Failiure,
      EndModelingFailed,
      ReloadComponentFailed,
    }
  }
}
